﻿using Vboot.Core.Module.Bpm;

namespace Vboot.Core.Module.Sys;

//DEMO分类服务
public class SysCoopCateService : BaseCateService<SysCoopCate>, ITransient
{
    
    public async Task Insert(SysCoopCate cate)
    {
        cate.avtag = true;
        if (string.IsNullOrEmpty(cate.id))
        {
            cate.id = YitIdHelper.NextId() + ""; 
        }
        cate.crmid = XuserUtil.getUserId();
        cate.crtim = DateTime.Now;
        //处理tier
        if (cate.pid != null)
        {
            var parentTier = await repo.Context.Queryable<SysCoopCate>()
                .Where(it => it.id == cate.pid).Select(it => it.tier).SingleAsync();
            cate.tier = parentTier + cate.id + "x";
        }
        else
        {
            cate.tier = "x" + cate.id + "x";
        }
        await repo.Context.Insertable(cate).ExecuteCommandAsync();
        SysOrg sysOrg = new SysOrg(cate.id, cate.name, 64);
        await _orgRepo.InsertAsync(sysOrg);

    }
    public async Task Update(SysCoopCate cate)
    {
        Console.WriteLine(cate);
        cate.upmid = XuserUtil.getUserId();
        cate.uptim = DateTime.Now;
        if (cate.pid != null)
        {
            var parentTier = await repo.Context.Queryable<SysCoopCate>()
                .Where(it => it.id == cate.pid).Select(it => it.tier).SingleAsync();
            cate.tier = parentTier + cate.id + "x";
            var arr = parentTier.Split("x");
            if (arr.Any(str => cate.id == str))
            {
                throw new Exception("父分类不能为自己或者自己的子分类");
            }
        }
        else
        {
            cate.tier = "x" + cate.id + "x";
        }

        var olderTier = await repo.Context.Queryable<SysCoopCate>()
            .Where(it => it.id == cate.id).Select(it => it.tier).SingleAsync();
        
        await repo.Context.Updateable(cate).ExecuteCommandAsync();
        SysOrg sysOrg = new SysOrg(cate.id, cate.name, 64);
        await _orgRepo.UpdateAsync(sysOrg);
        
        await DealCateTier(olderTier, cate.tier, cate.id);
        await DealUserTier(olderTier, cate.tier);
    }
    
    private async Task DealCateTier(string oldTier, string newTier, string id)
    {
        var idNameList = await
            repo.Context.Ado.SqlQueryAsync<ZidName>(
                "select id,tier as name from sys_coop_cate where tier like @oldTier and id<>@id",
                new {id, oldTier = oldTier + "%"});

        var dtList = new List<Dictionary<string, object>>();
        foreach (var idName in idNameList)
        {
            var dt = new Dictionary<string, object>
            {
                {"id", idName.id}, {"tier", idName.name.Replace(oldTier, newTier)}
            };
            dtList.Add(dt);
        }

        await repo.Context.Updateable(dtList).AS("sys_coop_cate").WhereColumns("id").ExecuteCommandAsync();
    }

    private async Task DealUserTier(string oldTier, string newTier)
    {
        var idNameList = await
            repo.Context.Ado.SqlQueryAsync<ZidName>(
                "select id,tier as name from sys_coop_user where tier like @oldTier",
                new {oldTier = oldTier + "%"});

        var list = new List<Dictionary<string, object>>();
        foreach (var idName in idNameList)
        {
            var dt = new Dictionary<string, object>
            {
                {"id", idName.id}, {"tier", idName.name.Replace(oldTier, newTier)}
            };
            list.Add(dt);
        }
        
        await repo.Context.Updateable(list).AS("sys_coop_user").WhereColumns("id").ExecuteCommandAsync();
    }
    
    //级联查询
    public async Task<SysCoopCate> Select(string id)
    {
        var cate = await repo.Context.Queryable<SysCoopCate>()
            .Where(it => it.id == id)
            .Includes(t => t.crman)
            .Includes(t => t.upman)
            .SingleAsync();
        if (cate.pid != null)
        {
            cate.pname = await repo.Context.Queryable<SysCoopCate>()
                .Where(it => it.id == cate.pid).Select(it => it.name).SingleAsync();
        }
        return cate;
    }

    private SqlSugarRepository<SysOrg> _orgRepo;
    
    public SysCoopCateService(SqlSugarRepository<SysCoopCate> repo,
        SqlSugarRepository<SysOrg> orgRepo)
    {
        this.repo = repo;
        _orgRepo = orgRepo;
    }
}